package System;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import control.TerminateExamcontrol;
import gui.Login.loginGui;
import gui.Principal.ChangingExamTimeGui;
import gui.Principal.StatisticInformation;
import gui.Principal.SystemInfo;
import gui.Student.AvailableExam;
import gui.Student.ComputerizedExam;
import gui.Student.GradesReview;
import gui.Student.StudentMainPanel;
import gui.Teacher.AddExamGui;
import gui.Teacher.AddQuestionGui;
import gui.Teacher.ChangeTimeGui;
import gui.Teacher.EnableExamGui;
import gui.Teacher.BlockForm;
import gui.Teacher.RemoveExamGui;
import gui.Teacher.RemoveQuestionGui;
import gui.Teacher.StatisticsGui;
import gui.Teacher.TeacherMainMenu;
import gui.Teacher.TerminateExam;
import BaseClasses.User;
import gui.Principal.PrincipalMainPanel;

/**
 * This class functions as a static class that runs the main client thread
 * and sets the screens. also used to function as a main system
 * @author Group 9
 *
 */
public class MainControl 
{
	
	public static Font guiFont = new Font("Microsoft New Tai Lue", Font.BOLD, 15);
	public static Font MainPanelFont = new Font("Microsoft New Tai Lue", Font.BOLD, 12);
	public static Dimension btnsDimesion = new Dimension(115,30);
	public static Color	 colorApprove = new Color(0,0,225);
	
	public static StudentMainPanel StudentGUI;
	public static AvailableExam avlExam;
	public static ComputerizedExam compExam;
	public static GradesReview grdReview;
	
	public static TeacherMainMenu TeacherGUI;
	public static TerminateExam exm;
	
	public static StatisticsGui stsGui;
	public static RemoveExamGui remEGui;
	public static RemoveQuestionGui remQuesGui;
	public static EnableExamGui enaExamGui;
	public static ChangeTimeGui chTimeGui;
	public static AddQuestionGui ADDqGui;
	public static AddExamGui addEGui;
	public static BlockForm exam;
	public static StatisticsGui statistic;
	public static PrincipalMainPanel PricipalGUI;
	public static StatisticInformation StatisticInfo;
	public static SystemInfo SysInfo;
	public static ChangingExamTimeGui ChETime;
	public static int guiX = 300, guiY = 200;
	public static int MainPanButX = 136 , MainPanButY = 66;
	public static ClientConsole client = null;
	public static User currentUser = null;
	public static JFrame frame;
	public static loginGui LoginScreenGui;
	public static ImageIcon IconAssReview = new ImageIcon("Icons\\AssRev.png");
	

	
	/**
	 * initiate a new JFrame and starts Login
	 */
	public static void main(String[] args) 
	{
		frame = new JFrame();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setLocation(guiX, guiY);
		frame.setVisible(true);
		/** add Login Screen to panel frame**/
		LoginScreenGui = new loginGui();
		setScreen(null,LoginScreenGui);

	}
	
	/**
	 * This Method Log the current user out of the system and initiate all variables
	 *  ( by calling to Terminate() )
	 */
	public static void LogOut(Component terminatingComp)
	{
		SystemObject result;
		client.send(new SystemObject(currentUser,SysMode.LogOut));
		result = (SystemObject) client.getResult();
		JOptionPane.showMessageDialog(null,result.getObj(),"System Message", JOptionPane.INFORMATION_MESSAGE);
		LoginScreenGui = new loginGui();
		setScreen(terminatingComp, MainControl.LoginScreenGui);
		Terminate();
	}
	
	/**
	 * This method terminates all the gui windows and closes the connection to the client
	 */
	private static void Terminate()
	{
		closeClientConnection();
		currentUser = null;
		LoginScreenGui=null;
	}
	
	
	/**
	 * This method sets the client connection if a client obj is already
	 * exists then the method only renew its connection to the server
	 * @param Host the host (IP) to connect to
	 * @param Port the port to connect to
	 * @throws Exception in case it isn't possible to initiate client
	 */
	public static void setClientConnection(String Host,int Port) throws Exception
	{
		if (client == null)
			client = new ClientConsole(Host, Port);
		else
			client.renewConnection();
	}
	
	/**
	 * This method close the client connection
	 */
	private static void closeClientConnection()
	{
		try{client.terminateConnection();}
		catch(Exception ex){client = null;}
	}
	
	
	/**
	 * This Method remove and old component from the frame and adds the new one to it
	 * In case old Component is null only the new one will be added. also resizing the frame to the newComp sizes
	 * @param oldComp the old component to dispose
	 * @param newComp the new component to set
	 */
	public static void setScreen(Component oldComp, Component newComp)
	{		
		if (oldComp != null)
		{
			oldComp.setVisible(false);
			frame.remove(oldComp);
		}
		if (newComp != null)
		{
			frame.add(newComp);
			frame.setLocation(guiX,guiY);
			frame.setSize(newComp.getSize());
			newComp.setVisible(true);
		}
	}
	

	/**
	 * This method sets the current user
	 * @param user the current user
	 */
	public static void setCurrentUser( User user)
	{
		currentUser = user;
	}
	
	
	/**
	 * This method set the Teacher panel according to the mode supplied
	 * @param mode the window panel to open
	 */
	public static void setTeacherWindows(int mode)
	{
		Component comp = null;
		switch(mode)
		{
			case 1:
				comp = (addEGui = new AddExamGui());
				break;
			case 2:
				comp = (remEGui = new RemoveExamGui());
				break;
			case 3:
				comp = (ADDqGui = new AddQuestionGui());
				break;
			case 4:
				comp = (remQuesGui = new RemoveQuestionGui());
				break;
			case 5:
				comp = (statistic = new StatisticsGui());
			break;
			case 6: 
				//comp = (exm = new TerminateExam());
				comp= (exam = new BlockForm());
		}
		setScreen(TeacherGUI,comp);
	}
	
	public static void setStudentWindows(int mode)
	{
		Component comp = null;
		switch(mode)
		{
			case 1:
				comp = (avlExam = new AvailableExam());
				break;
			case 2:
				comp = (grdReview = new GradesReview());
				break;
	/*		case 3:
				comp = (StudentFileReviewGUI = new StudentFileReviewForm()); 
				break;*/
		}
		setScreen(StudentGUI,comp);
	}

		/**
	 * This method set the Principal panel according to the mode supplied
	 * @param mode the window panel to open
	 */
	public static void setPrincipalGUI(int mode)
	{
		Component comp = null;
		switch(mode)
		{
			case 1:
				comp = StatisticInfo = new StatisticInformation();
				break;
			case 2:
				comp = SysInfo = new SystemInfo();
				break;
			case 3:
				comp = ChETime = new ChangingExamTimeGui();
				break;
		}
		setScreen(MainControl.PricipalGUI,comp);	
	}
	
	/**
	 * This method sets the GUI screen according to the User type provided
	 * @param usrType the user type came from Login screen
	 */
	public static void setGUI(int usrType,Component thisComp)
	{
		Component comp = null;
		switch(usrType)
		{
/*			case User.SECRETARY:
			{
				comp = SecretaryGUI = new SecretaryMainPanel();
				break;
			}
*/
			case User.TEACHER:
			{
				comp = TeacherGUI = new TeacherMainMenu();
				break;
			}
		case User.PRINCIPAL:
			{
				comp = PricipalGUI = new PrincipalMainPanel();
				break;
			}
			case User.STUDENT:
			{
				comp = StudentGUI = new StudentMainPanel();
				break;
			}		}
		setScreen(thisComp,comp);		
	}
	
	/**
	 * This is a generic method that sends a message to Message table in data base
	 * @param msg the message to send
	 * @return the answer from data base. either mode is OK and obj is an approval string
	 * 			or mode is Not_OK / connFail and obj is an error string
	 */
	/*public static SystemObject sendApprovalRequestToPrincipal(Message msg)
	{
		client.send(new SystemObject(msg,SysMode.UpdateMessageToPrincipal));
		return ( (systemObject) client.getResult() );
	}*/
	
	/**
	 * This is a generic method to upload a file to server
	 * @param obj the object[] which contains the array size, file, query and variables:<p>
	 * 		obj[0] -  is the SysFile file object to upload<p>
	 * 		obj[1] - is the Prepared statement Query contains (?,?,...)<p>
	 * 		obj[2],...,obj[size-1] - is the values for the prepared statement Query<p> 
	 *
	  * @return the answer from data base. either mode is OK and obj is an approval string
	 * 			or mode is Not_OK / connFail and obj is an error string
	 */
/*	public static SystemObject uploadFile(Object obj)
	{
		client.send(new systemObject(obj,SysMode.fileUpload));
		return ( (systemObject) client.getResult() );
	}
	*/
	/**
	 * This is a generic method for testings<br>
	 * will execute a query or an update and returns the result
	 * @param obj - an object[] holding the parms for query<br>
	 * 				obj[0] - the prepared statement's query (SELECT..FROM..WHERE..=? AND ...)<br>
	 * 				obj[1] - a boolean var, either true if this is an update or false if not<br>
	 * 				obj[2]..obj[N] - the variables for the query - (?,?,?..)
	 * @return a system Object with the result and mode OK or an error message if mode is NOT_OK.
	 */
	public static SystemObject sysCheck(Object[] obj)
	{
		client.send(new SystemObject(obj,SysMode.sysCheck));
		return ( (SystemObject) client.getResult() );
	}
	

	
}
